#include "remote_UART.h"

uint8_t dbus_buf[DBUS_MAX_LEN];
volatile RCControlTypeDef RC_DATA;

/**
  * @brief       handle received rc data
  * @param		 buff: the buff which saved raw rc data
  * @retval 
  */
void rc_callback_handler(uint8_t *buff)
{
	RC_DATA.rc_ch0 = (buff[0] | buff[1] << 8) & 0x07FF;
	RC_DATA.rc_ch0 -= 1024;
	RC_DATA.rc_ch1 = (buff[1] >> 3 | buff[2] * 32) & 0x07FF;
	RC_DATA.rc_ch1 -= 1024;
	RC_DATA.rc_ch2 = (buff[2] / 64 | buff[3] * 4 | buff[4] * 1024) & 0x07FF;
	RC_DATA.rc_ch2 -= 1024;
	RC_DATA.rc_ch3 = (buff[4] / 2 | buff[5] * 128) & 0x07FF;
	RC_DATA.rc_ch3 -= 1024;

	RC_DATA.rc_s1 = ((buff[5] >> 4) & 0x000C) >> 2;
	RC_DATA.rc_s2 = (buff[5] >> 4) & 0x0003;

	RC_DATA.mouse_x = ((int16_t)buff[6]) | ((int16_t)buff[7] << 8);
	RC_DATA.mouse_y = ((int16_t)buff[8]) | ((int16_t)buff[9] << 8);
	RC_DATA.mouse_z = ((int16_t)buff[10]) | ((int16_t)buff[11] << 8);
	RC_DATA.mouse_press_l = buff[12];
	RC_DATA.mouse_press_r = buff[13];
	RC_DATA.key_v = ((int16_t)buff[14]) | ((uint16_t)buff[15] << 8);
	RC_DATA.yaw = (((int16_t)buff[16] | ((int16_t)buff[17] << 8)) & 0x07FF) - 1024;

	if (RC_DATA.rc_ch0 > 660)
		RC_DATA.rc_ch0 = 660;
	if (RC_DATA.rc_ch0 < -660)
		RC_DATA.rc_ch0 = -660;
	if (RC_DATA.rc_ch1 > 660)
		RC_DATA.rc_ch1 = 660;
	if (RC_DATA.rc_ch1 < -660)
		RC_DATA.rc_ch1 = -660;
	if (RC_DATA.rc_ch2 > 660)
		RC_DATA.rc_ch2 = 660;
	if (RC_DATA.rc_ch2 < -660)
		RC_DATA.rc_ch2 = -660;
	if (RC_DATA.rc_ch3 > 660)
		RC_DATA.rc_ch3 = 660;
	if (RC_DATA.rc_ch3 < -660)
		RC_DATA.rc_ch3 = -660;
	if (RC_DATA.yaw > 660)
		RC_DATA.yaw = 660;
	if (RC_DATA.yaw < -660)
		RC_DATA.yaw = -660;
}

/**
  * @brief      callback this function when uart interrupt 
  * @param[in]  huart: uart IRQHandler id
  * @retval  
  */
void uart_receive_handler(UART_HandleTypeDef *huart)
{
	if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) &&
		__HAL_UART_GET_IT_SOURCE(huart, UART_IT_IDLE))
	{
		/* clear idle it flag avoid idle interrupt all the time */
		__HAL_UART_CLEAR_IDLEFLAG(huart);

		/* handle received data in idle interrupt */
		if (huart == &DBUS_HUART)
		{
			volatile uint8_t x;
			/* handle dbus data dbus_buf from DMA */
			if ((uint8_t)(huart->pRxBuffPtr - dbus_buf) == DBUS_BUFLEN)
			{
				rc_callback_handler(dbus_buf);
			}
			huart->pRxBuffPtr = dbus_buf;
		}
		HAL_UART_Receive_IT(&DBUS_HUART, dbus_buf, DBUS_MAX_LEN);
	}
}

/**
  * @brief   initialize dbus uart device 
  * @param   
  * @retval  
  */
void Dbus_UART_Init(void)
{
	/* open uart idle it */
	__HAL_UART_CLEAR_IDLEFLAG(&DBUS_HUART);
	__HAL_UART_ENABLE_IT(&DBUS_HUART, UART_IT_IDLE | UART_IT_RXNE);
	HAL_UART_Receive_IT(&DBUS_HUART, dbus_buf, DBUS_MAX_LEN);
}
